package com.likeyoudo.views.activity;

import android.text.Editable;
import android.text.TextWatcher;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.os.Bundle;

import cn.hutool.core.util.StrUtil;

import com.alibaba.fastjson2.JSON;
import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.CacheMemoryStaticUtils;
import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.EncodeUtils;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.google.android.material.textfield.TextInputEditText;
import com.google.android.material.textfield.TextInputLayout;
import com.likeyoudo.common.BaseActivity;
import com.likeyoudo.common.constant.HttpStatus;
import com.likeyoudo.common.constant.LoginInfoSP;
import com.likeyoudo.common.msg.MsgEvent;
import com.likeyoudo.common.utils.CommonUtils;
import com.likeyoudo.views.databinding.ActivityLoginBinding;
import com.likeyoudo.views.utils.HttpRequest;
import com.likeyoudo.views.R;
import com.likeyoudo.views.api.LoginApi;
import com.likeyoudo.views.type.response.CaptchaImageResponse;
import com.likeyoudo.views.type.dto.LoginDto;
import com.likeyoudo.views.type.response.LoginResponse;

import okhttp3.RequestBody;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

/**
 * @author LikeYouDo
 */
public class LoginActivity extends BaseActivity {

    private final SPUtils loginInfo = LoginInfoSP.getSPUtils();
    private LoginDto loginDto;
    ActivityLoginBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityLoginBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        initView();
    }

    @Override
    protected int getLayoutId() {
        return R.layout.activity_login;
    }

    public void onClick(View view) {
        if (view.getId() == R.id.login_button) {

            TextInputEditText code = findViewById(R.id.code);
            TextInputEditText usernameEt = findViewById(R.id.username);
            TextInputEditText passwordEt = findViewById(R.id.password);
            String username = usernameEt.getText().toString();
            String password = passwordEt.getText().toString();

            // 登录成功才保存
            // 判断是否为空
            TextInputLayout usernameLayout = findViewById(R.id.usernameTextInputLayout);
            TextInputLayout passwordLayout = findViewById(R.id.passwordTextInputLayout);
            TextInputLayout codeLayout = findViewById(R.id.codeTextInputLayout);
            if (StrUtil.hasBlank(username, password) || (code.getVisibility() == View.VISIBLE && StrUtil.isBlank(code.getText().toString()))) {
                if (StrUtil.isBlank(username)) {
                    // 设置报错
                    usernameLayout.setError("请输入用户名");
                } else {
                    usernameLayout.setError(null);
                }
                if (StrUtil.isBlank(password)) {
                    // 设置报错
                    passwordLayout.setError("请输入密码");
                } else {
                    passwordLayout.setError(null);
                }
                if (code.getVisibility() == View.VISIBLE && StrUtil.isBlank(code.getText().toString())) {
                    // 设置报错
                    codeLayout.setError("请输入验证码");
                } else {
                    codeLayout.setError(null);
                }
                // 取消所有的焦点
                CommonUtils.clearFocus(this);
            } else {
                // 取消所有的报错
                usernameLayout.setError(null);
                passwordLayout.setError(null);
                codeLayout.setError(null);
                // 取消所有的焦点
                CommonUtils.clearFocus(this);
                // 设置dto
                loginDto = loginDto == null ? new LoginDto() : loginDto;
                loginDto.setUsername(username);
                loginDto.setPassword(password);
                if (code.getVisibility() == View.VISIBLE) {
                    loginDto.setCode(code.getText().toString());
                }
                LoginApi.login(RequestBody.create(JSON.toJSONString(loginDto), HttpRequest.JSON_TYPE));
            }
        } else if (view.getId() == R.id.captcha) {
            LoginApi.getCodeImg();
        }
    }

    private void initView() {
        setImmersiveWindows();
        // 判断是否已经登录
        String token = loginInfo.getString(LoginInfoSP.TOKEN);
        if (StrUtil.isNotBlank(token)) {
            toIndex(token);
        } else {
            LoginApi.getCodeImg();
        }

        EditText username = findViewById(R.id.username);
        TextInputEditText password = findViewById(R.id.password);
        // 设置密码隐藏
        password.setTransformationMethod(PasswordTransformationMethod.getInstance());

        // 加载存储器
        // 判断是否保存了用户数据
        if (loginInfo.getBoolean(LoginInfoSP.REMEMBER_ME)) {
            // 读取数据并设置
            username.setText(loginInfo.getString(LoginInfoSP.LOGIN_USER_NAME));
            password.setText(loginInfo.getString(LoginInfoSP.LOGIN_USER_PWD));
            CheckBox rememberMe = findViewById(R.id.remember_me);
            rememberMe.setChecked(loginInfo.getBoolean(LoginInfoSP.REMEMBER_ME));
        }
        // 监听文本输入
        binding.code.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 当文本改变后，清除错误提示
                if (!StrUtil.isEmpty(s)) {
                    binding.codeTextInputLayout.setError(null); // 清除错误信息
                }
            }
        });
        binding.password.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 当文本改变后，清除错误提示
                if (!StrUtil.isEmpty(s)) {
                    binding.passwordTextInputLayout.setError(null); // 清除错误信息
                }
            }
        });
        binding.username.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                // 当文本改变后，清除错误提示
                if (!StrUtil.isEmpty(s)) {
                    binding.usernameTextInputLayout.setError(null); // 清除错误信息
                }
            }
        });

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(MsgEvent event) {
        switch (event.getType()) {
            case LoginApi.CAPTCHA:
                CaptchaImageResponse captchaImageMsg = event.getResponse(CaptchaImageResponse.class);
                handleCaptcha(captchaImageMsg);
                break;
            case LoginApi.LOGIN:
                LoginResponse loginMsg = event.getResponse(LoginResponse.class);
                handleLogin(loginMsg);
                break;
        }
    }

    private void handleLogin(LoginResponse loginMsg) {
        // 登录成功才保存
        if (loginMsg.getCode() == HttpStatus.SUCCESS) {
            // 保存token,仅当退出和token失效时才重新登录
            loginInfo.put(LoginInfoSP.TOKEN, loginMsg.getToken());
            // 判断是否勾选记住密码
            CheckBox checkBox = findViewById(R.id.remember_me);
            if (checkBox.isChecked()) {
                loginInfo.put(LoginInfoSP.LOGIN_USER_NAME, loginDto.getUsername());
                loginInfo.put(LoginInfoSP.LOGIN_USER_PWD, loginDto.getPassword());
                loginInfo.put(LoginInfoSP.REMEMBER_ME, true, true);
            } else {
                // 清除保存记录
                loginInfo.remove(LoginInfoSP.LOGIN_USER_NAME);
                loginInfo.remove(LoginInfoSP.LOGIN_USER_PWD);
                loginInfo.put(LoginInfoSP.REMEMBER_ME, false, true);
            }
            toIndex(loginMsg.getToken());
        } else {
            if (loginMsg.getMsg().contains("验证码")) {
                ((TextInputEditText) findViewById(R.id.code)).setText("");
                ((TextInputLayout) findViewById(R.id.codeTextInputLayout)).setError(loginMsg.getMsg());
            } else {
                ToastUtils.showLong(loginMsg.getMsg());
            }
            LoginApi.getCodeImg();
        }
    }

    private void toIndex(String token) {
        // 保存token到缓存
        CacheMemoryStaticUtils.put(LoginInfoSP.TOKEN, token);

        // 跳转到首页
        ActivityUtils.startActivity(IndexActivity.class);

        finish();
    }

    private void handleCaptcha(CaptchaImageResponse captchaImageMsg) {
        ImageView img = findViewById(R.id.captcha);
        View code = findViewById(R.id.code);
        if (captchaImageMsg.getCode() == HttpStatus.SUCCESS && captchaImageMsg.getCaptchaEnabled()) {
            loginDto = new LoginDto();
            // 验证码显示
            img.setVisibility(View.VISIBLE);
            code.setVisibility(View.VISIBLE);
            binding.codeTextInputLayout.setVisibility(View.VISIBLE);
            // 设置uuid
            loginDto.setUuid(captchaImageMsg.getUuid());
            // 读取base64并转化设置
            img.setImageBitmap(ConvertUtils.bytes2Bitmap(EncodeUtils.base64Decode(captchaImageMsg.getImg())));
            // 设置img撑满容器
            img.setScaleType(ImageView.ScaleType.FIT_XY);
        } else {
            // 验证码隐藏和文本框隐藏
            img.setVisibility(View.GONE);
            code.setVisibility(View.GONE);
            binding.codeTextInputLayout.setVisibility(View.GONE);
        }
    }

}